#include "stringprotocol.h"
#include "log/logger.h"


std::shared_ptr<StringMessage> StringMessage::CreateMessage(const std::string &cmd, const std::string &argsStr)
{
    auto msg = std::shared_ptr<StringMessage>(new StringMessage());
        
    msg->Cmd = cmd;
    msg->ArgsStr = argsStr;
    
    return msg;
}

std::shared_ptr<StringMessage> StringMessage::CreateMessage(const std::string &cmd, const std::vector<std::string> &args)
{
    auto msg = std::shared_ptr<StringMessage>(new StringMessage());
    
    msg->Cmd = cmd;
    msg->Args = args;
    
    return msg;
}

std::string StringMessage::ToString()
{
    return Cmd + " " + RawStr;
}

StringProtocol::StringProtocol()
{
}

StringProtocol::~StringProtocol()
{
}

int StringProtocol::Packet(std::shared_ptr<IProtocolMessage> msg)
{
    if(msg == nullptr)
        return 0;

    auto tagMsg = msg->As<StringMessage>();
    if(tagMsg->Cmd.empty())
        return 0;
    
    int index = 0;
    for(int i = 0; i < tagMsg->Cmd.size(); i++)
    {
        m_sendLine[index++] = tagMsg->Cmd.at(i);
    }
    m_sendLine[index++] = ' ';

    if(!tagMsg->ArgsStr.empty())
    {
        for(int i = 0; i < tagMsg->ArgsStr.size(); i++)
        {
            m_sendLine[index++] = tagMsg->ArgsStr.at(i);
        }
    }

    m_sendLine[index++] = STRING_PROTOCOL_ETX;

    return index;
}

uint8_t *StringProtocol::GetSendBuffer()
{
    return m_sendLine;
}

std::shared_ptr<IProtocolMessage> StringProtocol::Parse(uint8_t b)
{
    std::shared_ptr<IProtocolMessage> msg = nullptr;

    if(b == STRING_PROTOCOL_ETX)
    {
        msg = ParseHandle();
        m_recvLine.clear();
    }
    else
    {
        if(m_recvLine.size() >= STRING_PROTOCOL_LINE_MAX_LEN) //error
        {
            m_recvLine.clear();
        }

        m_recvLine += b;
    }

    return msg;
}

void StringProtocol::Reset()
{
    m_recvLine.clear();
}

bool StringProtocol::IsAck(std::shared_ptr<IProtocolMessage> sendMsg, std::shared_ptr<IProtocolMessage> recvMsg)
{
    return false;
}

bool StringProtocol::IsResponse(std::shared_ptr<IProtocolMessage> sendMsg, std::shared_ptr<IProtocolMessage> recvMsg)
{
    return false;
}

std::shared_ptr<IProtocolMessage> StringProtocol::ParseHandle()
{
    if(m_recvLine.size() <= 0)
        return nullptr;  

    std::vector<std::string> list = StringEx::Split(m_recvLine, " ", true, true);
    if(list.size() == 0)
        return nullptr;

    auto msg = std::shared_ptr<StringMessage>(new StringMessage);

    msg->Cmd = list[0];
    list.erase(list.begin());
    if(list.size() > 0)
    {
        msg->Args = std::move(list);
    }
    msg->RawStr = m_recvLine;

    return msg;
}

void StringProtocol::DumpErrorMessage()
{
    LogDebug()<<m_recvLine;
}
